package com.whoyx.jiebing.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.whoyx.jiebing.dao.entity.CommonWordEntity;
import com.whoyx.jiebing.dao.entity.MsgConversationEntity;
import com.whoyx.jiebing.dao.entity.MsgRecordEntity;
import com.whoyx.jiebing.dao.entity.UserEntity;
import com.whoyx.jiebing.dao.service.ICommonWordService;
import com.whoyx.jiebing.dao.service.IMsgConversationService;
import com.whoyx.jiebing.dao.service.IMsgRecordService;
import com.whoyx.jiebing.dao.service.IUserService;
import com.whoyx.jiebing.domain.BasePageReqDto;
import com.whoyx.jiebing.domain.enums.DeleteEnum;
import com.whoyx.jiebing.domain.enums.MsgTypeEnum;
import com.whoyx.jiebing.domain.msg.resp.MsgDataRespDtoV2;
import com.whoyx.jiebing.domain.req.DoctorAddCommonWordReqDto;
import com.whoyx.jiebing.domain.req.DoctorCommonWordModifyReqDto;
import com.whoyx.jiebing.domain.req.MsgRecordPageReqDto;
import com.whoyx.jiebing.domain.resp.BaseUrlRespDto;
import com.whoyx.jiebing.domain.resp.ConsultDataRespDto;
import com.whoyx.jiebing.domain.resp.DoctorCommonWordRespDto;
import com.whoyx.jiebing.domain.resp.UploadUrlRespDto;
import com.whoyx.jiebing.service.AsyncService;
import com.whoyx.jiebing.service.DoctorService;
import com.whoyx.jiebing.utils.BaseException;
import com.whoyx.jiebing.utils.PageResult;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class DoctorServiceImpl implements DoctorService {
    private final ICommonWordService iCommonWordService;
    private final IMsgRecordService iMsgRecordService;
    private final IMsgConversationService iMsgConversationService;
    private final IUserService iUserService;
    private final AsyncService asyncService;

    @Value("${tim.serviceUid}")
    private String serviceUid;
    @Value("${third.debug}")
    private boolean thirdDebug;
    @Value("${third.guidanceUrl}")
    private String guidanceUrl;


    @Override
    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    public void addCommonWord(DoctorAddCommonWordReqDto reqDto) {
        String uid = StpUtil.getLoginIdAsString();
        CommonWordEntity commonWordEntity = iCommonWordService.getOne(
                Wrappers.<CommonWordEntity>lambdaQuery()
                        .eq(CommonWordEntity::getCommonWord, reqDto.getContent())
                        .eq(CommonWordEntity::getUid, uid)
        );
        if (commonWordEntity != null) {
            throw new BaseException(403, "该条常用语已存在");
        }
        commonWordEntity = new CommonWordEntity();
        commonWordEntity.setUid(uid);
        commonWordEntity.setCommonWord(reqDto.getContent());
        commonWordEntity.setCreateBy(uid);
        commonWordEntity.setCreateTime(LocalDateTime.now());
        iCommonWordService.save(commonWordEntity);
    }

    @Override
    public PageResult<DoctorCommonWordRespDto> CommonWordPage(BasePageReqDto reqDto) {
        String uid = StpUtil.getLoginIdAsString();
        Page<CommonWordEntity> page = Page.of(reqDto.getPage(), reqDto.getSize());
        Page<CommonWordEntity> commonWordEntityPage = iCommonWordService.page(page, Wrappers.<CommonWordEntity>lambdaQuery()
                .eq(CommonWordEntity::getUid, uid)
                .orderByAsc(CommonWordEntity::getCreateTime));
        return PageResult.<DoctorCommonWordRespDto>builder()
                .page(reqDto.getPage())
                .size(reqDto.getSize())
                .total(commonWordEntityPage.getTotal())
                .list(commonWordEntityPage.getRecords().stream().map(i -> DoctorCommonWordRespDto.builder()
                        .commWordId(i.getId())
                        .content(i.getCommonWord())
                        .createTime(LocalDateTimeUtil.format(i.getCreateTime(), DatePattern.NORM_DATETIME_FORMATTER))
                        .build()).collect(Collectors.toList()))
                .build();
    }

    @Override
    public void commonWordModify(DoctorCommonWordModifyReqDto reqDto) {
        String uid = StpUtil.getLoginIdAsString();
        CommonWordEntity commonWordEntity = iCommonWordService.getOne(
                Wrappers.<CommonWordEntity>lambdaQuery()
                        .eq(CommonWordEntity::getUid, uid)
                        .eq(CommonWordEntity::getId, reqDto.getCommonWordId())
        );
        if (commonWordEntity == null) {
            throw new BaseException(403, "常用语不存在");
        }
        if (StringUtils.isBlank(reqDto.getContent())) {
            iCommonWordService.removeById(commonWordEntity);
        } else {
            commonWordEntity.setCommonWord(reqDto.getContent());
            commonWordEntity.setUpdateBy(uid);
            commonWordEntity.setUpdateTime(LocalDateTime.now());
            iCommonWordService.updateById(commonWordEntity);
        }
    }

    @Override
    public void commonWordDelete(Integer commonWordId) {
        String uid = StpUtil.getLoginIdAsString();
        iCommonWordService.remove(
                Wrappers.<CommonWordEntity>lambdaQuery()
                        .eq(CommonWordEntity::getId, commonWordId)
                        .eq(CommonWordEntity::getUid, uid)
        );
    }


    @Override
    public List<ConsultDataRespDto> consultList() {
        List<MsgConversationEntity> conversationEntityList = iMsgConversationService.list(
                Wrappers.<MsgConversationEntity>lambdaQuery()
                        .notLike(MsgConversationEntity::getConversationString, serviceUid)
                        .orderByDesc(MsgConversationEntity::getRecentMsgTime)
        );
        // 查询聊天记录
        Map<Integer, MsgRecordEntity> msgRecordEntityMap;
        if (!conversationEntityList.isEmpty()) {
            List<MsgRecordEntity> msgRecordEntityList = iMsgRecordService.list(
                    Wrappers.<MsgRecordEntity>lambdaQuery()
                            .in(MsgRecordEntity::getId, conversationEntityList.stream().map(MsgConversationEntity::getRecentMsgId).collect(Collectors.toList()))
//                            .eq(MsgRecordEntity::getDeleted, DeleteEnum.ENABLE.getValue())
            );
            msgRecordEntityMap = msgRecordEntityList.stream()
                    .map(e ->{
                        boolean isRevoked = !Objects.equals(e.getDeleted(), DeleteEnum.ENABLE.getValue());
                        if (isRevoked) {
                            List<Map<String,Object>> list = new ArrayList<>(1);
                            Map<String, Object> msgBodyMap = new HashMap<>();
                            msgBodyMap.put("msgType", MsgTypeEnum.TIMTextElem.getName());
                            msgBodyMap.put("msgContent","{\"Text\":\"消息已撤回\"}");
                            list.add(msgBodyMap);
                            e.setMsgBody(JSONUtil.toJsonStr(list));
                        }
                        return e;
                    })
                    .collect(Collectors.toMap(MsgRecordEntity::getConversationId, i -> i));
        } else {
            msgRecordEntityMap = new HashMap<>();
        }

        // 所有患者
        List<UserEntity> userEntityList = iUserService.list(
                Wrappers.<UserEntity>lambdaQuery()
                        .eq(UserEntity::getUserRole, 2)
        );
        Map<String, UserEntity> userEntityMap = userEntityList.stream().collect(Collectors.toMap(UserEntity::getUid, i -> i));
        List<ConsultDataRespDto> respList = new ArrayList<>();


        UserEntity drUserEntity = iUserService.validatedEntityByUid(StpUtil.getLoginIdAsString());

        conversationEntityList.forEach(i -> {
            String[] split = i.getConversationString().split("##");
            String patUid = split[1];
            UserEntity userEntity = userEntityMap.remove(patUid);
            if (userEntity != null) {
                MsgRecordEntity msgRecordEntity = msgRecordEntityMap.get(i.getId());
                respList.add(ConsultDataRespDto.builder()
                        .uid(patUid)
                        .headUrl(userEntity.getHeaderUrl())
                        .name(userEntity.getName())
                        .recentMsgData(msgRecordEntity == null ? null : MsgDataRespDtoV2.buildWithEntity(msgRecordEntity, StpUtil.getLoginIdAsString(), null))
                        .unReadNum(i.getUnreadMsgNum())
                        .userInfoUrl(getUserInfoUrl(userEntity.getOpenId(), drUserEntity.getOpenId()))
                        .build());
            }
        });

        userEntityMap.forEach((patUid, userEntity) -> {
            respList.add(ConsultDataRespDto.builder()
                    .uid(patUid)
                    .headUrl(userEntity.getHeaderUrl())
                    .name(userEntity.getName())
                    .unReadNum(0)
                    .userInfoUrl(getUserInfoUrl(userEntity.getOpenId(), drUserEntity.getOpenId()))
                    .build());
        });

        return respList;

    }

    @Override
    public BaseUrlRespDto questionnaireUrl(String patUid) {
        UserEntity userEntity = iUserService.validatedEntityByUid(patUid);
        String openId = userEntity.getOpenId();
        String path = guidanceUrl + "/index/" + openId + "&state=1";
        String questionnaireUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/live?opi=" + openId + "&return_url=" + path;
        if (thirdDebug) {
            questionnaireUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/live?opi=o6fsjuJsSpmRE1tf-0dlG7EesEA8" + "&return_url=" + path;
        }
        return BaseUrlRespDto.builder()
                .url(questionnaireUrl)
                .build();
    }

    @Override
    public BaseUrlRespDto uploadPictureUrl(String patUid) {
        UserEntity userEntity = iUserService.validatedEntityByUid(patUid);
        String openId = userEntity.getOpenId();
        String path = guidanceUrl + "/index/" + openId + "&state=1";
        String uploadPictureUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=" + openId + "&return_url=" + path;
        if (thirdDebug) {
            uploadPictureUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=o6fsjuJsSpmRE1tf-0dlG7EesEA8" + "&return_url=" + path;
        }
        return BaseUrlRespDto.builder()
                .url(uploadPictureUrl)
                .build();
    }

    @Override
    public UploadUrlRespDto uploadUrl(String patUid) {
//        UserEntity userEntity = iUserService.validatedEntityByUid(patUid);
//        String openId = userEntity.getOpenId();
//        String path = guidanceUrl + "/index/" + openId + "&state=1";
//        String uploadPictureUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=" + openId + "&return_url=" + path;
//        String questionnaireUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=" + openId + "&return_url=" + path;
//        if (thirdDebug) {
//            uploadPictureUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=o6fsjuJsSpmRE1tf-0dlG7EesEA8" + "&return_url=" + path;
//            questionnaireUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=o6fsjuJsSpmRE1tf-0dlG7EesEA8" + "&return_url=" + path;
//        }
        return asyncService.uploadUrl(patUid);
    }

    private String getUserInfoUrl(String openId, String dOpenId) {
//        UserEntity userEntity = iUserService.validatedEntityByUid(drUid);
//        String dOpenId = userEntity.getOpenId();
//        String path = guidanceUrl + "/consultList/" + dOpenId;
//        String userInfoUrl = "https://b.yicloud.org/dyn2/wx/2/1643/p/3157/live?opi=" + openId + "&popi=" + dOpenId + "&return_url=" + path;
//        if (thirdDebug) {
//            userInfoUrl = "https://b.yicloud.org/dyn2/wx/2/3069/p/admin?opi=o6fsjuImNhgzAQTm9sBekiweqXVc&popi=o6fsjuJsSpmRE1tf-0dlG7EesEA8" + "&return_url=" + path;
//        }
        return asyncService.getUserInfoUrl(openId,dOpenId);
    }

}
